home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / manageme / tcpdump-.001 / tcpdump-~ / tcpdump-3.0.2-linux / tcpdump-3.0.2 / print-decnet.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-21  |  20.5 KB  |  764 lines

  1. /*
  2.  * Copyright (c) 1992, 1993, 1994
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  */
  21.  
  22. #ifndef lint
  23. static char rcsid[] =
  24.     "@(#) $Header: print-decnet.c,v 1.15 94/06/20 19:44:38 leres Exp $ (LBL)";
  25. #endif
  26.  
  27. #include <sys/types.h>
  28. #include <sys/time.h>
  29. #include <sys/socket.h>
  30.  
  31. #include <net/if.h>
  32. #ifdef    DECNETLIB
  33. #include <netdnet/dnetdb.h>
  34. #endif
  35.  
  36. #include <ctype.h>
  37. #include <stdio.h>
  38. #ifdef __STDC__
  39. #include <stdlib.h>
  40. #endif
  41. #include <unistd.h>
  42.  
  43. #include "decnet.h"
  44. #include "interface.h"
  45. #include "addrtoname.h"
  46.  
  47. /* Forwards */
  48. static void print_decnet_ctlmsg(const union routehdr *, int);
  49. static void print_t_info(int);
  50. static void print_l1_routes(const char *, int);
  51. static void print_l2_routes(const char *, int);
  52. static void print_i_info(int);
  53. static void print_elist(const char *, int);
  54. static void print_nsp(const u_char *, int);
  55. static void print_reason(int);
  56. #ifdef    PRINT_NSPDATA
  57. static void pdata(u_char *, int);
  58. #endif
  59.  
  60. #ifdef    DECNETLIB
  61. extern char *dnet_htoa(struct dn_naddr *);
  62. #endif
  63.  
  64. void
  65. decnet_print(register const u_char *ap, register int length,
  66.          register int caplen)
  67. {
  68.     static union routehdr rhcopy;
  69.     register union routehdr *rhp = &rhcopy;
  70.     register int mflags;
  71.     int dst, src, hops;
  72.     int rhlen;
  73.     const u_char *nspp;
  74.     int nsplen;
  75.     int pktlen;
  76.  
  77.     if (length < sizeof(struct shorthdr)) {
  78.         (void)printf("[|decnet]");
  79.         return;
  80.     }
  81.  
  82.     pktlen = EXTRACT_16BITS(ap);
  83.  
  84.     rhlen = min(length, caplen);
  85.     rhlen = min(rhlen, sizeof(*rhp));
  86.     bcopy(&(ap[sizeof(short)]), rhp, rhlen);
  87.  
  88.     mflags = EXTRACT_8BITS(rhp->rh_short.sh_flags);
  89.  
  90.     if (mflags & RMF_PAD) {
  91.         /* pad bytes of some sort in front of message */
  92.         int padlen = mflags & RMF_PADMASK;
  93.         if (vflag)
  94.         (void) printf("[pad:%d] ", padlen);
  95.         ap += padlen;
  96.         length -= padlen;
  97.         caplen -= padlen;
  98.         rhlen = min(length, caplen);
  99.         rhlen = min(rhlen, sizeof(*rhp));
  100.         bcopy(&(ap[sizeof(short)]), rhp, rhlen);
  101.         mflags = EXTRACT_8BITS(rhp->rh_short.sh_flags);
  102.     }
  103.  
  104.     if (mflags & RMF_FVER) {
  105.         (void) printf("future-version-decnet");
  106.         default_print(ap, length);
  107.         return;
  108.     }
  109.  
  110.     /* is it a control message? */
  111.     if (mflags & RMF_CTLMSG) {
  112.         print_decnet_ctlmsg(rhp, min(length, caplen));
  113.         return;
  114.     }
  115.  
  116.     switch (mflags & RMF_MASK) {
  117.     case RMF_LONG:
  118.         dst = EXTRACT_16BITS(rhp->rh_long.lg_dst.dne_remote.dne_nodeaddr);
  119.         src = EXTRACT_16BITS(rhp->rh_long.lg_src.dne_remote.dne_nodeaddr);
  120.         hops = EXTRACT_8BITS(rhp->rh_long.lg_visits);
  121.         nspp = &(ap[sizeof(short) + sizeof(struct longhdr)]);
  122.         nsplen = min((length - sizeof(struct longhdr)),
  123.              (caplen - sizeof(struct longhdr)));
  124.         break;
  125.     case RMF_SHORT:
  126.         dst = EXTRACT_16BITS(rhp->rh_short.sh_dst);
  127.         src = EXTRACT_16BITS(rhp->rh_short.sh_src);
  128.         hops = (EXTRACT_8BITS(rhp->rh_short.sh_visits) & VIS_MASK)+1;
  129.         nspp = &(ap[sizeof(short) + sizeof(struct shorthdr)]);
  130.         nsplen = min((length - sizeof(struct shorthdr)),
  131.              (caplen - sizeof(struct shorthdr)));
  132.         break;
  133.     default:
  134.         (void) printf("unknown message flags under mask");
  135.         default_print((u_char *)ap, length);
  136.         return;
  137.     }
  138.  
  139.     (void)printf("%s > %s %d ",
  140.             dnaddr_string(src), dnaddr_string(dst), pktlen);
  141.     if (vflag) {
  142.         if (mflags & RMF_RQR)
  143.         (void)printf("RQR ");
  144.         if (mflags & RMF_RTS)
  145.         (void)printf("RTS ");
  146.         if (mflags & RMF_IE)
  147.         (void)printf("IE ");
  148.         (void)printf("%d hops ", hops);
  149.     }
  150.  
  151.     print_nsp(nspp, nsplen);
  152. }
  153.  
  154. static void
  155. print_decnet_ctlmsg(register const union routehdr *rhp, int length)
  156. {
  157.     int mflags = EXTRACT_8BITS(rhp->rh_short.sh_flags);
  158.     register union controlmsg *cmp = (union controlmsg *)rhp;
  159.     int src, dst, info, blksize, eco, ueco, hello, other, vers;
  160.     etheraddr srcea, rtea;
  161.     int priority;
  162.     char *rhpx = (char *)rhp;
  163.  
  164.     switch (mflags & RMF_CTLMASK) {
  165.     case RMF_INIT:
  166.         (void)printf("init ");
  167.         src = EXTRACT_16BITS(cmp->cm_init.in_src);
  168.         info = EXTRACT_8BITS(cmp->cm_init.in_info);
  169.         blksize = EXTRACT_16BITS(cmp->cm_init.in_blksize);
  170.         vers = EXTRACT_8BITS(cmp->cm_init.in_vers);
  171.         eco = EXTRACT_8BITS(cmp->cm_init.in_eco);
  172.         ueco = EXTRACT_8BITS(cmp->cm_init.in_ueco);
  173.         hello = EXTRACT_16BITS(cmp->cm_init.in_hello);
  174.         print_t_info(info);
  175.         (void)printf(
  176.         "src %sblksize %d vers %d eco %d ueco %d hello %d",
  177.             dnaddr_string(src), blksize, vers, eco, ueco,
  178.             hello);
  179.         break;
  180.     case RMF_VER:
  181.         (void)printf("verification ");
  182.         src = EXTRACT_16BITS(cmp->cm_ver.ve_src);
  183.         other = EXTRACT_8BITS(cmp->cm_ver.ve_fcnval);
  184.         (void)printf("src %s fcnval %o", dnaddr_string(src), other);
  185.         break;
  186.     case RMF_TEST:
  187.         (void)printf("test ");
  188.         src = EXTRACT_16BITS(cmp->cm_test.te_src);
  189.         other = EXTRACT_8BITS(cmp->cm_test.te_data);
  190.         (void)printf("src %s data %o", dnaddr_string(src), other);
  191.         break;
  192.     case RMF_L1ROUT:
  193.         (void)printf("lev-1-routing ");
  194.         src = EXTRACT_16BITS(cmp->cm_l1rou.r1_src);
  195.         (void)printf("src %s ", dnaddr_string(src));
  196.         print_l1_routes(&(rhpx[sizeof(struct l1rout)]),
  197.                 length - sizeof(struct l1rout));
  198.         break;
  199.     case RMF_L2ROUT:
  200.         (void)printf("lev-2-routing ");
  201.         src = EXTRACT_16BITS(cmp->cm_l2rout.r2_src);
  202.         (void)printf("src %s ", dnaddr_string(src));
  203.         print_l2_routes(&(rhpx[sizeof(struct l2rout)]),
  204.                 length - sizeof(struct l2rout));
  205.         break;
  206.     case RMF_RHELLO:
  207.         (void)printf("router-hello ");
  208.         vers = EXTRACT_8BITS(cmp->cm_rhello.rh_vers);
  209.         eco = EXTRACT_8BITS(cmp->cm_rhello.rh_eco);
  210.         ueco = EXTRACT_8BITS(cmp->cm_rhello.rh_ueco);
  211.         bcopy(&(cmp->cm_rhello.rh_src), &srcea, sizeof(srcea));
  212.         src = EXTRACT_16BITS(srcea.dne_remote.dne_nodeaddr);
  213.         info = EXTRACT_8BITS(cmp->cm_rhello.rh_info);
  214.         blksize = EXTRACT_16BITS(cmp->cm_rhello.rh_blksize);
  215.         priority = EXTRACT_8BITS(cmp->cm_rhello.rh_priority);
  216.         hello = EXTRACT_16BITS(cmp->cm_rhello.rh_hello);
  217.         print_i_info(info);
  218.         (void)printf(
  219.         "vers %d eco %d ueco %d src %s blksize %d pri %d hello %d",
  220.             vers, eco, ueco, dnaddr_string(src),
  221.             blksize, priority, hello);
  222.         print_elist(&(rhpx[sizeof(struct rhellomsg)]),
  223.                 length - sizeof(struct rhellomsg));
  224.         break;
  225.     case RMF_EHELLO:
  226.         (void)printf("endnode-hello ");
  227.         vers = EXTRACT_8BITS(cmp->cm_ehello.eh_vers);
  228.         eco = EXTRACT_8BITS(cmp->cm_ehello.eh_eco);
  229.         ueco = EXTRACT_8BITS(cmp->cm_ehello.eh_ueco);
  230.         bcopy(&(cmp->cm_ehello.eh_src), &srcea, sizeof(srcea));
  231.         src = EXTRACT_16BITS(srcea.dne_remote.dne_nodeaddr);
  232.         info = EXTRACT_8BITS(cmp->cm_ehello.eh_info);
  233.         blksize = EXTRACT_16BITS(cmp->cm_ehello.eh_blksize);
  234.         /*seed*/
  235.         bcopy(&(cmp->cm_ehello.eh_router), &rtea, sizeof(rtea));
  236.         dst = EXTRACT_16BITS(rtea.dne_remote.dne_nodeaddr);
  237.         hello = EXTRACT_16BITS(cmp->cm_ehello.eh_hello);
  238.         other = EXTRACT_8BITS(cmp->cm_ehello.eh_data);
  239.         print_i_info(info);
  240.         (void)printf(
  241.     "vers %d eco %d ueco %d src %s blksize %d rtr %s hello %d data %o",
  242.             vers, eco, ueco, dnaddr_string(src),
  243.             blksize, dnaddr_string(dst), hello, other);
  244.         break;
  245.  
  246.     default:
  247.         (void)printf("unknown control message");
  248.         default_print((u_char *)rhp, length);
  249.         break;
  250.     }
  251. }
  252.  
  253. static void
  254. print_t_info(int info)
  255. {
  256.     int ntype = info & 3;
  257.     switch (ntype) {
  258.     case 0: (void)printf("reserved-ntype? "); break;
  259.     case TI_L2ROUT: (void)printf("l2rout "); break;
  260.     case TI_L1ROUT: (void)printf("l1rout "); break;
  261.     case TI_ENDNODE: (void)printf("endnode "); break;
  262.     }
  263.     if (info & TI_VERIF)
  264.         (void)printf("verif ");
  265.     if (info & TI_BLOCK)
  266.         (void)printf("blo ");
  267. }
  268.  
  269. static void
  270. print_l1_routes(const char *rp, int len)
  271. {
  272.     int count;
  273.     int id;
  274.     int info;
  275.  
  276.     /* The last short is a checksum */
  277.     while (len > (3 * sizeof(short))) {
  278.         count = EXTRACT_16BITS(rp);
  279.         if (count > 1024)
  280.         return;    /* seems to be bogus from here on */
  281.         rp += sizeof(short);
  282.         len -= sizeof(short);
  283.         id = EXTRACT_16BITS(rp);
  284.         rp += sizeof(short);
  285.         len -= sizeof(short);
  286.         info = EXTRACT_16BITS(rp);
  287.         rp += sizeof(short);
  288.         len -= sizeof(short);
  289.         (void)printf("{ids %d-%d cost %d hops %d} ", id, id + count,
  290.                 RI_COST(info), RI_HOPS(info));
  291.     }
  292. }
  293.  
  294. static void
  295. print_l2_routes(const char *rp, int len)
  296. {
  297.     int count;
  298.     int area;
  299.     int info;
  300.  
  301.     /* The last short is a checksum */
  302.     while (len > (3 * sizeof(short))) {
  303.         count = EXTRACT_16BITS(rp);
  304.         if (count > 1024)
  305.         return;    /* seems to be bogus from here on */
  306.         rp += sizeof(short);
  307.         len -= sizeof(short);
  308.         area = EXTRACT_16BITS(rp);
  309.         rp += sizeof(short);
  310.         len -= sizeof(short);
  311.         info = EXTRACT_16BITS(rp);
  312.         rp += sizeof(short);
  313.         len -= sizeof(short);
  314.         (void)printf("{areas %d-%d cost %d hops %d} ", area, area + count,
  315.                 RI_COST(info), RI_HOPS(info));
  316.     }
  317. }
  318.  
  319. static void
  320. print_i_info(int info)
  321. {
  322.     int ntype = info & II_TYPEMASK;
  323.     switch (ntype) {
  324.     case 0: (void)printf("reserved-ntype? "); break;
  325.     case II_L2ROUT: (void)printf("l2rout "); break;
  326.     case II_L1ROUT: (void)printf("l1rout "); break;
  327.     case II_ENDNODE: (void)printf("endnode "); break;
  328.     }
  329.     if (info & II_VERIF)
  330.         (void)printf("verif ");
  331.     if (info & II_NOMCAST)
  332.         (void)printf("nomcast ");
  333.     if (info & II_BLOCK)
  334.         (void)printf("blo ");
  335. }
  336.  
  337. static void
  338. print_elist(const char *elp, int len)
  339. {
  340.     /* Not enough examples available for me to debug this */
  341. }
  342.  
  343. static void
  344. print_nsp(const u_char *nspp, int nsplen)
  345. {
  346.     const struct nsphdr *nsphp = (struct nsphdr *)nspp;
  347.     int dst, src, flags;
  348.  
  349.     flags = EXTRACT_8BITS(nsphp->nh_flags);
  350.     dst = EXTRACT_16BITS(nsphp->nh_dst);
  351.     src = EXTRACT_16BITS(nsphp->nh_src);
  352.  
  353.     switch (flags & NSP_TYPEMASK) {
  354.     case MFT_DATA:
  355.         switch (flags & NSP_SUBMASK) {
  356.         case MFS_BOM:
  357.         case MFS_MOM:
  358.         case MFS_EOM:
  359.         case MFS_BOM+MFS_EOM:
  360.         printf("data %d>%d ", src, dst);
  361.         {
  362.             struct seghdr *shp = (struct seghdr *)nspp;
  363.             int ack;
  364. #ifdef    PRINT_NSPDATA
  365.             u_char *dp;
  366. #endif
  367.             int data_off = sizeof(struct minseghdr);
  368.  
  369.             ack = EXTRACT_16BITS(shp->sh_seq[0]);
  370.             if (ack & SGQ_ACK) {    /* acknum field */
  371.             if ((ack & SGQ_NAK) == SGQ_NAK)
  372.                 (void)printf("nak %d ", ack & SGQ_MASK);
  373.             else
  374.                 (void)printf("ack %d ", ack & SGQ_MASK);
  375.                 ack = EXTRACT_16BITS(shp->sh_seq[1]);
  376.             data_off += sizeof(short);
  377.             if (ack & SGQ_OACK) {    /* ackoth field */
  378.                 if ((ack & SGQ_ONAK) == SGQ_ONAK)
  379.                 (void)printf("onak %d ", ack & SGQ_MASK);
  380.                 else
  381.                 (void)printf("oack %d ", ack & SGQ_MASK);
  382.                 ack = EXTRACT_16BITS(shp->sh_seq[2]);
  383.                 data_off += sizeof(short);
  384.             }
  385.             }
  386.             (void)printf("seg %d ", ack & SGQ_MASK);
  387. #ifdef    PRINT_NSPDATA
  388.             dp = &(nspp[data_off]);
  389.             pdata(dp, 10);
  390. #endif
  391.         }
  392.         break;
  393.         case MFS_ILS+MFS_INT:
  394.         printf("intr ");
  395.         {
  396.             struct seghdr *shp = (struct seghdr *)nspp;
  397.             int ack;
  398. #ifdef    PRINT_NSPDATA
  399.             u_char *dp;
  400. #endif
  401.             int data_off = sizeof(struct minseghdr);
  402.  
  403.             ack = EXTRACT_16BITS(shp->sh_seq[0]);
  404.             if (ack & SGQ_ACK) {    /* acknum field */
  405.             if ((ack & SGQ_NAK) == SGQ_NAK)
  406.                 (void)printf("nak %d ", ack & SGQ_MASK);
  407.             else
  408.                 (void)printf("ack %d ", ack & SGQ_MASK);
  409.                 ack = EXTRACT_16BITS(shp->sh_seq[1]);
  410.             data_off += sizeof(short);
  411.             if (ack & SGQ_OACK) {    /* ackdat field */
  412.                 if ((ack & SGQ_ONAK) == SGQ_ONAK)
  413.                 (void)printf("nakdat %d ", ack & SGQ_MASK);
  414.                 else
  415.                 (void)printf("ackdat %d ", ack & SGQ_MASK);
  416.                 ack = EXTRACT_16BITS(shp->sh_seq[2]);
  417.                 data_off += sizeof(short);
  418.             }
  419.             }
  420.             (void)printf("seg %d ", ack & SGQ_MASK);
  421. #ifdef    PRINT_NSPDATA
  422.             dp = &(nspp[data_off]);
  423.             pdata(dp, 10);
  424. #endif
  425.         }
  426.         break;
  427.         case MFS_ILS:
  428.         (void)printf("link-service %d>%d ", src, dst);
  429.         {
  430.             struct seghdr *shp = (struct seghdr *)nspp;
  431.             struct lsmsg *lsmp =
  432.             (struct lsmsg *)&(nspp[sizeof(struct seghdr)]);
  433.             int ack;
  434.             int lsflags, fcval;
  435.  
  436.             ack = EXTRACT_16BITS(shp->sh_seq[0]);
  437.             if (ack & SGQ_ACK) {    /* acknum field */
  438.             if ((ack & SGQ_NAK) == SGQ_NAK)
  439.                 (void)printf("nak %d ", ack & SGQ_MASK);
  440.             else
  441.                 (void)printf("ack %d ", ack & SGQ_MASK);
  442.                 ack = EXTRACT_16BITS(shp->sh_seq[1]);
  443.             if (ack & SGQ_OACK) {    /* ackdat field */
  444.                 if ((ack & SGQ_ONAK) == SGQ_ONAK)
  445.                 (void)printf("nakdat %d ", ack & SGQ_MASK);
  446.                 else
  447.                 (void)printf("ackdat %d ", ack & SGQ_MASK);
  448.                 ack = EXTRACT_16BITS(shp->sh_seq[2]);
  449.             }
  450.             }
  451.             (void)printf("seg %d ", ack & SGQ_MASK);
  452.             lsflags = EXTRACT_8BITS(lsmp->ls_lsflags);
  453.             fcval = EXTRACT_8BITS(lsmp->ls_fcval);
  454.             switch (lsflags & LSI_MASK) {
  455.             case LSI_DATA:
  456.             (void)printf("dat seg count %d ", fcval);
  457.             switch (lsflags & LSM_MASK) {
  458.             case LSM_NOCHANGE:
  459.                 break;
  460.             case LSM_DONOTSEND:
  461.                 (void)printf("donotsend-data ");
  462.                 break;
  463.             case LSM_SEND:
  464.                 (void)printf("send-data ");
  465.                 break;
  466.             default:
  467.                 (void)printf("reserved-fcmod? %x", lsflags);
  468.                 break;
  469.             }
  470.             break;
  471.             case LSI_INTR:
  472.             (void)printf("intr req count %d ", fcval);
  473.             break;
  474.             default:
  475.             (void)printf("reserved-fcval-int? %x", lsflags);
  476.             break;
  477.             }
  478.         }
  479.         break;
  480.         default:
  481.         (void)printf("reserved-subtype? %x %d > %d", flags, src, dst);
  482.         break;
  483.         }
  484.         break;
  485.     case MFT_ACK:
  486.         switch (flags & NSP_SUBMASK) {
  487.         case MFS_DACK:
  488.         (void)printf("data-ack %d>%d ", src, dst);
  489.         {
  490.             struct ackmsg *amp = (struct ackmsg *)nspp;
  491.             int ack;
  492.  
  493.             ack = EXTRACT_16BITS(amp->ak_acknum[0]);
  494.             if (ack & SGQ_ACK) {    /* acknum field */
  495.             if ((ack & SGQ_NAK) == SGQ_NAK)
  496.                 (void)printf("nak %d ", ack & SGQ_MASK);
  497.             else
  498.                 (void)printf("ack %d ", ack & SGQ_MASK);
  499.                 ack = EXTRACT_16BITS(amp->ak_acknum[1]);
  500.             if (ack & SGQ_OACK) {    /* ackoth field */
  501.                 if ((ack & SGQ_ONAK) == SGQ_ONAK)
  502.                 (void)printf("onak %d ", ack & SGQ_MASK);
  503.                 else
  504.                 (void)printf("oack %d ", ack & SGQ_MASK);
  505.             }
  506.             }
  507.         }
  508.         break;
  509.         case MFS_IACK:
  510.         (void)printf("ils-ack %d>%d ", src, dst);
  511.         {
  512.             struct ackmsg *amp = (struct ackmsg *)nspp;
  513.             int ack;
  514.  
  515.             ack = EXTRACT_16BITS(amp->ak_acknum[0]);
  516.             if (ack & SGQ_ACK) {    /* acknum field */
  517.             if ((ack & SGQ_NAK) == SGQ_NAK)
  518.                 (void)printf("nak %d ", ack & SGQ_MASK);
  519.             else
  520.                 (void)printf("ack %d ", ack & SGQ_MASK);
  521.                 ack = EXTRACT_16BITS(amp->ak_acknum[1]);
  522.             if (ack & SGQ_OACK) {    /* ackdat field */
  523.                 if ((ack & SGQ_ONAK) == SGQ_ONAK)
  524.                 (void)printf("nakdat %d ", ack & SGQ_MASK);
  525.                 else
  526.                 (void)printf("ackdat %d ", ack & SGQ_MASK);
  527.             }
  528.             }
  529.         }
  530.         break;
  531.         case MFS_CACK:
  532.         (void)printf("conn-ack %d", dst);
  533.         break;
  534.         default:
  535.         (void)printf("reserved-acktype? %x %d > %d", flags, src, dst);
  536.         break;
  537.         }
  538.         break;
  539.     case MFT_CTL:
  540.         switch (flags & NSP_SUBMASK) {
  541.         case MFS_CI:
  542.         case MFS_RCI:
  543.         if ((flags & NSP_SUBMASK) == MFS_CI)
  544.             (void)printf("conn-initiate ");
  545.         else
  546.             (void)printf("retrans-conn-initiate ");
  547.         (void)printf("%d>%d ", src, dst);
  548.         {
  549.             struct cimsg *cimp = (struct cimsg *)nspp;
  550.             int services, info, segsize;
  551. #ifdef    PRINT_NSPDATA
  552.             u_char *dp;
  553. #endif
  554.  
  555.             services = EXTRACT_8BITS(cimp->ci_services);
  556.             info = EXTRACT_8BITS(cimp->ci_info);
  557.             segsize = EXTRACT_16BITS(cimp->ci_segsize);
  558.  
  559.             switch (services & COS_MASK) {
  560.             case COS_NONE:
  561.             break;
  562.             case COS_SEGMENT:
  563.             (void)printf("seg ");
  564.             break;
  565.             case COS_MESSAGE:
  566.             (void)printf("msg ");
  567.             break;
  568.             case COS_CRYPTSER:
  569.             (void)printf("crypt ");
  570.             break;
  571.             }
  572.             switch (info & COI_MASK) {
  573.             case COI_32:
  574.             (void)printf("ver 3.2 ");
  575.             break;
  576.             case COI_31:
  577.             (void)printf("ver 3.1 ");
  578.             break;
  579.             case COI_40:
  580.             (void)printf("ver 4.0 ");
  581.             break;
  582.             case COI_41:
  583.             (void)printf("ver 4.1 ");
  584.             break;
  585.             }
  586.             (void)printf("segsize %d ", segsize);
  587. #ifdef    PRINT_NSPDATA
  588.             dp = &(nspp[sizeof(struct cimsg)]);
  589.             pdata(dp, nsplen - sizeof(struct cimsg));
  590. #endif
  591.         }
  592.         break;
  593.         case MFS_CC:
  594.         (void)printf("conn-confirm %d>%d ", src, dst);
  595.         {
  596.             struct ccmsg *ccmp = (struct ccmsg *)nspp;
  597.             int services, info, segsize, optlen;
  598. #ifdef    PRINT_NSPDATA
  599.             u_char *dp;
  600. #endif
  601.  
  602.             services = EXTRACT_8BITS(ccmp->cc_services);
  603.             info = EXTRACT_8BITS(ccmp->cc_info);
  604.             segsize = EXTRACT_16BITS(ccmp->cc_segsize);
  605.             optlen = EXTRACT_8BITS(ccmp->cc_optlen);
  606.  
  607.             switch (services & COS_MASK) {
  608.             case COS_NONE:
  609.             break;
  610.             case COS_SEGMENT:
  611.             (void)printf("seg ");
  612.             break;
  613.             case COS_MESSAGE:
  614.             (void)printf("msg ");
  615.             break;
  616.             case COS_CRYPTSER:
  617.             (void)printf("crypt ");
  618.             break;
  619.             }
  620.             switch (info & COI_MASK) {
  621.             case COI_32:
  622.             (void)printf("ver 3.2 ");
  623.             break;
  624.             case COI_31:
  625.             (void)printf("ver 3.1 ");
  626.             break;
  627.             case COI_40:
  628.             (void)printf("ver 4.0 ");
  629.             break;
  630.             case COI_41:
  631.             (void)printf("ver 4.1 ");
  632.             break;
  633.             }
  634.             (void)printf("segsize %d ", segsize);
  635.             if (optlen) {
  636.             (void)printf("optlen %d ", optlen);
  637. #ifdef    PRINT_NSPDATA
  638.             optlen = min(optlen, nsplen - sizeof(struct ccmsg));
  639.             dp = &(nspp[sizeof(struct ccmsg)]);
  640.             pdata(dp, optlen);
  641. #endif
  642.             }
  643.         }
  644.         break;
  645.         case MFS_DI:
  646.         (void)printf("disconn-initiate %d>%d ", src, dst);
  647.         {
  648.             struct dimsg *dimp = (struct dimsg *)nspp;
  649.             int reason, optlen;
  650. #ifdef    PRINT_NSPDATA
  651.             u_char *dp;
  652. #endif
  653.  
  654.             reason = EXTRACT_16BITS(dimp->di_reason);
  655.             optlen = EXTRACT_8BITS(dimp->di_optlen);
  656.  
  657.             print_reason(reason);
  658.             if (optlen) {
  659.             (void)printf("optlen %d ", optlen);
  660. #ifdef    PRINT_NSPDATA
  661.             optlen = min(optlen, nsplen - sizeof(struct dimsg));
  662.             dp = &(nspp[sizeof(struct dimsg)]);
  663.             pdata(dp, optlen);
  664. #endif
  665.             }
  666.         }
  667.         break;
  668.         case MFS_DC:
  669.         (void)printf("disconn-confirm %d>%d ", src, dst);
  670.         {
  671.             struct dcmsg *dcmp = (struct dcmsg *)nspp;
  672.             int reason;
  673.  
  674.             reason = EXTRACT_16BITS(dcmp->dc_reason);
  675.  
  676.             print_reason(reason);
  677.         }
  678.         break;
  679.         default:
  680.         (void)printf("reserved-ctltype? %x %d > %d", flags, src, dst);
  681.         break;
  682.         }
  683.         break;
  684.     default:
  685.         (void)printf("reserved-type? %x %d > %d", flags, src, dst);
  686.         break;
  687.     }
  688. }
  689.  
  690. struct token reason2str[] = {
  691.     { UC_OBJREJECT,        "object rejected connect" },
  692.     { UC_RESOURCES,        "insufficient resources" },
  693.     { UC_NOSUCHNODE,    "unrecognized node name" },
  694.     { DI_SHUT,        "node is shutting down" },
  695.     { UC_NOSUCHOBJ,        "unrecognized object" },
  696.     { UC_INVOBJFORMAT,    "invalid object name format" },
  697.     { UC_OBJTOOBUSY,    "object too busy" },
  698.     { DI_PROTOCOL,        "protocol error discovered" },
  699.     { DI_TPA,        "third party abort" },
  700.     { UC_USERABORT,        "user abort" },
  701.     { UC_INVNODEFORMAT,    "invalid node name format" },
  702.     { UC_LOCALSHUT,        "local node shutting down" },
  703.     { DI_LOCALRESRC,    "insufficient local resources" },
  704.     { DI_REMUSERRESRC,    "insufficient remote user resources" },
  705.     { UC_ACCESSREJECT,    "invalid access control information" },
  706.     { DI_BADACCNT,        "bad ACCOUNT information" },
  707.     { UC_NORESPONSE,    "no response from object" },
  708.     { UC_UNREACHABLE,    "node unreachable" },
  709.     { DC_NOLINK,        "no link terminate" },
  710.     { DC_COMPLETE,        "disconnect complete" },
  711.     { DI_BADIMAGE,        "bad image data in connect" },
  712.     { DI_SERVMISMATCH,    "cryptographic service mismatch" },
  713.     { 0,            NULL }
  714. };
  715.  
  716. static void
  717. print_reason(register int reason)
  718. {
  719.     printf("%s ", tok2str(reason2str, "reason-%d", reason));
  720. }
  721.  
  722. char *
  723. dnnum_string(u_short dnaddr)
  724. {
  725.     char *str;
  726.     int area = (dnaddr & AREAMASK) >> AREASHIFT;
  727.     int node = dnaddr & NODEMASK;
  728.  
  729.     str = (char *)malloc(sizeof("00.0000"));
  730.     sprintf(str, "%d.%d", area, node);
  731.     return(str);
  732. }
  733.  
  734. char *
  735. dnname_string(u_short dnaddr)
  736. {
  737. #ifdef    DECNETLIB
  738.     struct dn_naddr dna;
  739.  
  740.     dna.a_len = sizeof(short);
  741.     bcopy((char *)&dnaddr, dna.a_addr, sizeof(short));
  742.     return (savestr(dnet_htoa(&dna)));
  743. #else
  744.     return(dnnum_string(dnaddr));    /* punt */
  745. #endif
  746. }
  747.  
  748. #ifdef    PRINT_NSPDATA
  749. static void
  750. pdata(u_char *dp, int maxlen)
  751. {
  752.     char c;
  753.     int x = maxlen;
  754.  
  755.     while (x-- > 0) {
  756.         c = *dp++;
  757.         if (isprint(c))
  758.         putchar(c);
  759.         else
  760.         printf("\\%o", c & 0xFF);
  761.     }
  762. }
  763. #endif
  764.